package pd_server

import (
	"context"
	"crypto/tls"
	"log"
	"net"
	"sync"
	"time"

	"github.com/quic-go/quic-go"
)

type QuicClient struct {
	oriConn  net.PacketConn
	quicConn quic.Connection

	mutex sync.Mutex
	once  sync.Once
}

func NewQuicClient(oriConn net.PacketConn) *QuicClient {
	return &QuicClient{
		oriConn: oriConn,
	}
}

func (tis *QuicClient) Clise() {
	if conn := tis.quicConn; conn != nil {
		_ = conn.CloseWithError(0, "")
		tis.quicConn = nil
	}
}

// 建立连接, 在一个udp连接上不要重复建立连接
func (tis *QuicClient) dial() {
	tlsConf := &tls.Config{
		InsecureSkipVerify: true,
		NextProtos:         []string{"quic-echo-example"},
	}

	conn, err := quic.Dial(context.TODO(), tis.oriConn, &net.UDPAddr{
		IP:   net.ParseIP("127.0.0.1"),
		Port: 4242,
	}, tlsConf, &quic.Config{
		KeepAlivePeriod: time.Second * 10,
	})
	if err != nil {
		log.Println(err)
		return
	}

	tis.quicConn = conn
}

func (tis *QuicClient) OpenStream(ctx context.Context) (quic.Stream, error) {
	tis.mutex.Lock()
	defer tis.mutex.Unlock()

	tis.once.Do(tis.dial)

	stream, err := tis.quicConn.OpenStreamSync(ctx)
	if err != nil {
		log.Printf("quicClient.OpenStreamSync fail, %v", err)
	}
	return stream, err
}
